#include <iostream>
#include <mutex>
#include <atomic>
#include <unistd.h>

using namespace std;

template <class T>
class my_shared_ptr
{
public:
	my_shared_ptr(T* ptr = nullptr)
		: _ptr(ptr), _mtx(new mutex), _count(new int(1))
	{
		cout << "构造" << '\n';
	}

	my_shared_ptr(const my_shared_ptr<T>& sp)
		: _ptr(sp._ptr), _count(sp._count), _mtx(sp._mtx)
	{
		AddRef();   // 增加引用计数
	}

	~my_shared_ptr()
	{
		Release();  // 删除操作
	}

    // 赋值重载 需要先将已有的资源释放 减少的是原来的对象的引用计数
	my_shared_ptr<T>& operator=(const my_shared_ptr<T>& sp)
	{   // 防止自赋值
		if (sp._ptr == _ptr) return *this;
        Release();
        _ptr = sp._ptr;
        _mtx = sp._mtx;
        _count = sp._count;
        AddRef();

        return *this;
	}

	T& operator*() {
        return *this;
    }

    T* operator->() {
        return _ptr;
    }

    T* get() {
        return _ptr;
    }
	
private:
	void AddRef()
	{
		_mtx->lock();
		(*_count)++;
		_mtx->unlock();
	}

	void Release()
	{
		_mtx->lock();
		bool flag = false;
		if (--(*_count) == 0 && _ptr)
		{
			cout << "析构" << '\n';
			delete _ptr;
			delete _count;
			_ptr = nullptr;
            _count = nullptr;
			flag = true;
		}
		_mtx->unlock();

		if (flag) {
            delete _mtx;
            _mtx = nullptr;
        }
	}

private:
	T* _ptr;
	mutex* _mtx;
	int* _count;
};


template <class T>
class my_unique_ptr
{
public:
	my_unique_ptr(T* ptr)
		: _ptr(ptr)
	{
		cout << "构造" << endl;
	}

	~my_unique_ptr()
	{
		if (_ptr)
		{
			cout << "析构" << endl;
			delete _ptr;
			_ptr = nullptr;
		}
	}

	T& operator*()
	{
		return *_ptr;
	}

	T* operator->()
	{
		return _ptr;
	}

	my_unique_ptr<T>& operator=(const my_unique_ptr<T>&) = delete;
	my_unique_ptr(const my_unique_ptr<T>&) = delete;

private:
	T* _ptr;
};

// 一个简单的类，用于测试
class MyClass
{
public:
    MyClass(int value) : value(value) {
        std::cout << "MyClass constructed with value: " << value << std::endl;
    }

    ~MyClass() {
        std::cout << "MyClass destructed" << std::endl;
    }

    void print() const {
        std::cout << "Value: " << value << std::endl;
    }

private:
    int value;
};


int main()
{
	my_shared_ptr<MyClass> smc(new MyClass(10));
	my_unique_ptr<MyClass> umc(new MyClass(20));

	sleep(1);

    return 0;
}